﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

using Azure.Logger;

namespace Azure.Core
{
    internal class AzPageLoader
    {
        private Uri _uri = null;
        private int _maxRetryCount = 5;
        private int _timeOutDelay = 30000;
        private int _retryDelay = 5000;

        public AzPageLoader(String uri, int maxRetryCount, int timeOutDelay)
        {
            try
            {
                this._maxRetryCount = maxRetryCount;
                this._timeOutDelay = timeOutDelay;
                this._uri = new Uri(uri);
            }
            catch (UriFormatException ex)
            {
                AzLogger.Error("Uri = " + uri + "格式不正确", ex);
                this._uri = null;

                throw;
            }
        }

        public String Load()
        {
            String html = String.Empty;
            //虽然应该不会是NULL，但是还是防范一下
            if (this._uri != null)
            {
                HttpWebRequest request = null;
                try
                {
                    request = HttpWebRequest.Create(this._uri) as HttpWebRequest;
                }
                catch (Exception ex)
                {
                    AzLogger.Error("创建HttpWebRequest失败", ex);
                }

                //返回空html
                if (request == null)
                {
                    AzLogger.Error("Uri = " + this._uri.ToString() + "不能创建HttpWebRequest对象，请检查协议类型");
                    return html;
                }

                request.AllowAutoRedirect = false;
                request.Timeout = this._timeOutDelay;

                HttpWebResponse response = null;
                for (int i = 0; i < this._maxRetryCount ; i++)
                {
                    try
                    {
                        response = request.GetResponse() as HttpWebResponse;
                        //成功了就离开
                        break;
                    }
                    catch (Exception ex)
                    {
                        AzLogger.Error("获得HttpWebResponse失败", ex);
                        System.Threading.Thread.Sleep(this._retryDelay);
                    }
                }
                    
                //返回空html
                if (response == null)
                {
                    AzLogger.Error("Uri = " + this._uri.ToString() + "不能创建HttpWebResponse对象，请检查协议类型");
                    return html;
                }

                //获得页面编码
                System.Text.Encoding encoding = System.Text.Encoding.GetEncoding(response.CharacterSet);

                if (encoding == null)
                {
                    AzLogger.Error(response.CharacterSet + "是无效的字符集");
                    response.Close();

                    return html;
                }

                bool loadOK = false;
                Stream stream = response.GetResponseStream();
                StreamReader sr = new StreamReader(stream, encoding);

                for (int i = 0; i < this._maxRetryCount && !loadOK; i++)
                {
                    try
                    {
                        html = sr.ReadToEnd();
                        loadOK = true;
                    }
                    catch (Exception ex)
                    {
                        AzLogger.Error("第" + (i + 1).ToString() + "次下载页面" + this._uri.ToString() + " 超时", ex);
                        //等待一段时间再尝试
                        System.Threading.Thread.Sleep(this._retryDelay);
                    }
                }

                if (!loadOK)
                {
                    AzLogger.Error("对页面" + this._uri.ToString() + this._maxRetryCount + "次尝试全部都失败");
                }

                //资源释放
                if (sr != null)
                    sr.Close();

                if (stream != null)
                    stream.Close();

                response.Close();

                return html;
            }
            else
            {
                return html;
            }//end if (this._uri != null)
        }
    }
}